package com.qfedu.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qfedu.common.Md5;
import com.qfedu.user.dto.PasswordDto;
import com.qfedu.user.dto.StateDto;
import com.qfedu.user.dto.UserDto;
import com.qfedu.user.mapper.UserMapper;
import com.qfedu.user.pojo.User;
import com.qfedu.user.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.Date;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Transactional(readOnly = true)
    @Override
    public Page<User> getUsers(UserDto userDto) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(User::getUsername,User::getName, User::getSex,
                User::getAge, User::getPhone, User::getEmail,User::getEntryTime,
                User::getLeaveTime, User::getCreatedTime, User::getState, User::getRoleId);
        String name = userDto.getName();
        wrapper.like(StringUtils.hasLength(name), User::getName, name);
        Integer sex = userDto.getSex();
        wrapper.eq(sex != null, User::getSex, sex);
        String phone = userDto.getPhone();
        wrapper.like(StringUtils.hasLength(phone), User::getPhone, phone);

        Page<User> page = new Page<>(userDto.getCurrentPage(), userDto.getPageSize());
        return page(page, wrapper);
    }

    @Transactional(readOnly = true)
    @Override
    public Integer login(User user, HttpSession session) {
        User dbUser = getById(user.getUsername());
        if(dbUser == null) return -1;//不存在
        Integer state = dbUser.getState();
        if(state == 0) return  -2; //冻结
        String encrypt = Md5.encrypt(user.getPassword());
        if (dbUser.getPassword().equals(encrypt)) {
            session.setAttribute("username", user.getUsername());
            session.setAttribute("userPermissions", Arrays.asList("searchUser", "addUser", "updateUser", "changeUserState"));
            return 1;
        } else return 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean changeUserState(StateDto stateDto) {
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(User::getState, stateDto.getNewState());
        wrapper.eq(User::getUsername, stateDto.getUsername());
        wrapper.eq(User::getState, stateDto.getOldState());
        return update(wrapper);
    }

    @Transactional(rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ)
    @Override
    public Boolean changeUserPassword(PasswordDto passwordDto) {
        User dbUser = getById(passwordDto.getUsername());
        if(dbUser == null) return false;
        String encrypt = Md5.encrypt(passwordDto.getOldPwd());
        if(dbUser.getPassword().equals(encrypt)){
            encrypt = Md5.encrypt(passwordDto.getNewPwd());
            LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
            wrapper.set(User::getPassword, encrypt);
            wrapper.eq(User::getUsername, passwordDto.getUsername());
            return update(wrapper);
        } else return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateById(User user) {
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        String name = user.getName();
        wrapper.set(StringUtils.hasLength(name), User::getName, name);
        Integer sex = user.getSex();
        wrapper.set(sex != null, User::getSex, sex);
        Integer age = user.getAge();
        wrapper.set(age != null, User::getAge, age);
        String phone = user.getPhone();
        wrapper.set(StringUtils.hasLength(phone), User::getPhone, phone);
        String email = user.getEmail();
        wrapper.set(StringUtils.hasLength(email), User::getEmail, email);
        Integer state = user.getState();
        wrapper.set(state != null, User::getState, state);
        Date entryTime = user.getEntryTime();
        wrapper.set(entryTime != null, User::getEntryTime, entryTime);
        Date leaveTime = user.getLeaveTime();
        wrapper.set(leaveTime != null, User::getLeaveTime, leaveTime);
        Integer roleId = user.getRoleId();
        wrapper.set(roleId != null, User::getRoleId, roleId);
        wrapper.eq(User::getUsername, user.getUsername());
        return update(wrapper);
    }
}
